package com.goodbyegirl1974.cardGameProto.manager
{
	import com.goodbyegirl1974.cardGameProto.config.GameConfig;
	import com.goodbyegirl1974.cardGameProto.parts.Attack;
	import com.goodbyegirl1974.cardGameProto.parts.BattleParameter;
	import com.goodbyegirl1974.cardGameProto.player.GamePlayer;

	public class BattleManager
	{
		private var _player0:GamePlayer;
		private var _player0DataXML:XML;
		private var _player1:GamePlayer;
		private var _player1DataXML:XML;
		private var _nowTurn:int;
		private var _battleParamter:BattleParameter;
		
		/**
		 * コンストラクタ。
		 * @param player0DataXML
		 * @param player1DataXML
		 * 
		 */		
		public function BattleManager(player0DataXML:XML, player1DataXML:XML)
		{
			init(player0DataXML, player1DataXML);
		}
		
		/**
		 * 初期化。
		 */		
		private function init(player0DataXML:XML, player1DataXML:XML):void
		{
			this._player0 = new GamePlayer(player0DataXML);
			this._player1 = new GamePlayer(player1DataXML);
			this._battleParamter = BattleParameter.getInstance();
		}
		
		/**
		 * 戦闘。
		 * 
		 */		
		public function battle():void
		{
			//攻撃側、棒行側の設定。
			var attackPlayer:GamePlayer;
			var deffencePlayer:GamePlayer;
			if(_nowTurn == 0)
			{
				attackPlayer = this._player0;
				deffencePlayer = this._player1;
				this._nowTurn = 1;
			}
			else if(_nowTurn == 1)
			{
				attackPlayer = this._player0;
				deffencePlayer = this._player1;
				this._nowTurn = 0;
			}
			//攻撃側が使用するAttackを指定。
			//攻撃側のオプションチェック
			//防御側のパラメータチェック
			//防御側のオプションチェック
			//攻撃側命中率と防御側回避率を演算して、最終的な命中率を確定。
			//最終的な攻撃力などを決定。
			//TODO:以下一行、本来はユーザーが選択したキーを設定する。
			var attackKey:String = GameConfig.ATTACK_KEY_HEADER + "01";
			this._battleParamter.attackKey = attackKey;
			//TODO:各パラメータの設定。アイテムや、敵の状態に応じての補正値の組み込みを今後行うこと。
			attackPlayer.setBattleParamterFromCard(GameConfig.TURN_ATTACK);
			deffencePlayer.setBattleParamterFromCard(GameConfig.TURN_DEFFENCE);
			//ここまでで、各カードのパラメータ反映済み。	
			var targetAttack:Attack = this._battleParamter.attack;
			var attackNum:int = targetAttack.attackNum + this._battleParamter.attackPlusNum;
			var i:int = 0;
			var hitRate:Number = targetAttack.hitRate + this._battleParamter.hitRatePlusNum;
			var totalDamageNum:Number = 0.0;
			var damageNum:Number = targetAttack.damageNum + this._battleParamter.damagePlusNum;
			var attackRate:Number = 0.0;
			for(i; i<attackNum; i++)
			{
				var rnd:int = Math.floor(Math.random());
				if(rnd <= hitRate)
				{
					//攻撃があたっている。
					totalDamageNum += damageNum;
				}
			}
			//属性から判断しての、totalDamagePointの再計算
			var damageRate:Number = this.getDamageRate(deffencePlayer.parameter.playerKind, targetAttack.attackKind);
			totalDamageNum *= damageRate;
			//トータルダメージとHPの比較
			deffencePlayer.parameter.hpPoint -= totalDamageNum;
			this._battleParamter.result = getResult(deffencePlayer.parameter.hpPoint, attackRate);
			this._battleParamter.deffencePlayerStatus = this.getDeffencePlayerStatus(targetAttack);;
			//結果を画面表示すること。
			this.showResult();
		}
		
		private function showResult():void
		{
			// TODO Auto Generated method stub
		}
		
		
		/**
		 * 攻撃のダメージの調整値を取得するファンクション。
		 * @param playerKind
		 * @param attackKind
		 * 
		 */		
		private function getDamageRate(playerKind:String, attackKind:String):Number
		{
			//本来は、防御側プレイヤー属性と攻撃の属性との組み合わせに応じてdamageRateが決まる。
			//現在は仮で固定値を代入しています。
			//TODO:本来のDamageRateの計算式設定。
			var damageRate:Number = 1;
			return damageRate;
		}
		
		/**
		 * 攻撃結果のステータスを取得する。
		 * @param hp
		 * @param attackRate
		 * @return 
		 * 
		 */		
		private function getResult(hp:Number, attackRate:Number):String
		{
			var result:String;
			if(hp <= 0)
				result = GameConfig.RESULT_DOWN;
			else if(attackRate > 1)
				result = GameConfig.RESULT_CRITICAL;
			else
				result = GameConfig.RESULT_NORMAL
			return result;
		}
		
		/**
		 * 防御側プレーヤーが、引数で指定された特殊状態になるかならないかを、指定された割合から判定する。
		 * @param statusKind
		 * @param rate
		 * @return 
		 * 
		 */		
		private function getDeffencePlayerStatus(targetAttack:Attack):String
		{
			var counter:Number = Math.random();
			var status:String = GameConfig.STATUS_NORMAL;
			if(counter < targetAttack.statusEffectRate)
				status = targetAttack.statusEffect;
			return status;
		}
		
		/**
		 * 攻撃側の攻撃力を算出。
		 * @param player
		 * @return 
		 * 
		 */		
		private function getAttackPoint(player:GamePlayer, attackKey:String):Number
		{
			//攻撃力の算出方法は、攻撃回数分だけ、攻撃の当たり判定を行い、あたった回数×ダメージ、で総ダメージを算出。
			var attackNum:Number;
			return attackNum;
		}
	}
}